package com.fakesmoker.aidawnda.job;/**
 * @program: aidawnda
 * @author: lcy
 * @create: 2025-01-10 18:57
 * <p>
 * 2025/1/10,
 * <p>
 * 2025/1/10,
 */

/**
 2025/1/10,
 */

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fakesmoker.aidawnda.common.ResultUtils;
import com.fakesmoker.aidawnda.config.RedissonConfig;
import com.fakesmoker.aidawnda.model.entity.App;
import com.fakesmoker.aidawnda.model.entity.User;
import com.fakesmoker.aidawnda.service.AppService;
import com.fakesmoker.aidawnda.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 缓存预热设计
 */
@Slf4j
@Component
public class PreCacheJob {
    @Resource
    private UserService userService;
    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private AppService appService;

    @Resource
    private RedissonClient redissonClient;

    //白名单用户
    private final static List<Long> WHITES_IDS = Arrays.asList(1L);

    //每个注册用户
    private List<Long> REGISTER_USERS_IDS = Arrays.asList(1L);

    private final static String RLOCK_USER_INDEX_KEY = "aidawnda:user:doCache";
    private final static String RLOCK_APP_INDEX_KEY = "aidawnda:app:doCache";

    @Scheduled(cron = "0 55 17 * * *")
    public void doRecommendCacheUsers() {
        RLock lock = redissonClient.getLock(RLOCK_USER_INDEX_KEY);
        try {
            if (lock.tryLock(0, -1, TimeUnit.SECONDS)) {
                ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();

                for (Long id : WHITES_IDS) {
                    String redisKey = String.format("user_recommend_%s", id);

                    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
                    Page<User> userPage = userService.page(new Page<>(1, 20),
                            queryWrapper);
                    try {
                        valueOperations.set(redisKey, userPage, 1, TimeUnit.DAYS);
                    } catch (Exception e) {
                        log.error("redis set error", e);
                    }
                }
            }
        } catch (InterruptedException e) {
            System.out.println("redis set error");
            throw new RuntimeException(e);
        } finally {
            if (lock != null && lock.isLocked()) {
                if (lock.isHeldByCurrentThread()) { //保证是当前的线程持有锁才能释放
                    lock.unlock();
                    System.out.printf("log.info(释放锁成功)%S", Thread.currentThread().getId());
                    log.info("释放锁成功" + Thread.currentThread().getId());
                }
            }
        }


    }

    @Scheduled(cron = "0 31 19 * * *")
    public void doRecommendCacheApps() {

        RLock lock = redissonClient.getLock(RLOCK_APP_INDEX_KEY);

        try {
            if (lock.tryLock(0, -1, TimeUnit.SECONDS)) {

                ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
                List<User> userList = userService.list();
                REGISTER_USERS_IDS = userList.stream().map(User::getId).collect(Collectors.toList());
                for (Long id : REGISTER_USERS_IDS) {
                    String redisKey = String.format("app_recommend_%s", id);

                    QueryWrapper<App> queryWrapper = new QueryWrapper<>();
                    Page<App> appPage = appService.page(new Page<>(1, 20),
                            queryWrapper);
                    try {
                        valueOperations.set(redisKey, appPage, 1, TimeUnit.DAYS);
                    } catch (Exception e) {
                        log.error("redis set error", e);
                    }
                }
            }
        } catch (InterruptedException e) {
            System.out.println("redis set error");
            throw new RuntimeException(e);
        } finally {
            if (lock != null && lock.isLocked()) {
                if (lock.isHeldByCurrentThread()) { //保证是当前的线程持有锁才能释放
                    lock.unlock();
                    System.out.printf("log.info(释放锁成功)%S", Thread.currentThread().getId());
                    log.info("释放锁成功" + Thread.currentThread().getId());
                }
            }
        }


    }
}
